﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using ASPNETMVC4Tutorial.Models;
using ASPNETMVC4Tutorial.Filters;

namespace ASPNETMVC4Tutorial.Controllers
{
    /// <summary>
    /// The four main HTTP methods (GET, PUT, POST, and DELTETE) can be mapped to CRUD operations as follows:
    //GET retrieves the representation of the resource at a specified URI. GET should have no side effects on the server.
    //PUT updates a resource at a specified URI. PUT can also be used to create a new resource at a specified URI, if the server allows clients to specify new URIs. For this tutorial, the API will not support creation through PUT.
    //POST creates a new resource. The server assigns the URI for the new object and returns this URI as part of the response message.
    //DELETE deletes a resource at a specified URI.
    /// </summary>
    //[NotImplExceptionFilterAttribute]
    public class ApiProductsController : ApiController
    {

        private readonly IProductRepository repository;

        public ApiProductsController(IProductRepository repository)
        {
            if (repository == null)
            {
                throw new ArgumentNullException("repository");
            }
            this.repository = repository;
        }


        #region GET
        /// <summary>
        /// /api/ApiProducts
        /// </summary>
        /// <returns></returns>
        [AjaxOnly]
        public IEnumerable<Product> GetProducts()
        {
            return repository.GetAll();
        }

        /// <summary>
        /// /api/ApiProducts/?name=name
        /// </summary>
        /// <returns></returns>
        [NotImplExceptionFilterAttribute]
        public IEnumerable<Product> GetProductByName(string name)
        {
            throw new NotImplementedException("This action WrongAction is not implemented. ");
        }

        /// <summary>
        /// /api/ApiProducts/?id=id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Product GetProductById(int id)
        {
            Product product = repository.Get(id);
            if (product == null)
            {
                //throw new HttpResponseException(HttpStatusCode.NotFound);

                HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.NotFound)
                {
                  Content = new StringContent(string.Format("No product with ID = {0}", id)),
                  ReasonPhrase = "Product ID Not Found"
                  
                };
                throw new HttpResponseException(response);
            }

            return product;
        }

        /// <summary>
        /// /api/ApiProducts/?category=category
        /// </summary>
        /// <param name="category"></param>
        /// <returns></returns>
        [RequireHttps]
        public IEnumerable<Product> GetProductByCategory(string category)
        {
            return repository.GetAll().Where(p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase));

        }

        #endregion

        #region POST
        /// <summary>
        /// /api/ApiProducts
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        /// Response code: By default, the Web API framework sets the response status code to 200 (OK). But according to the HTTP/1.1 protocol, when a POST request results in the creation of a resource, the server should reply with status 201 (Created).
        /// Location: When the server creates a resource, it should include the URI of the new resource in the Location header of the response.
        public HttpResponseMessage PostProduct(Product item)
        {
            item = repository.Add(item);
            var response = Request.CreateResponse<Product>(HttpStatusCode.Created, item);

            string uri = Url.Link("DefaultApi", new { id = item.Id });
            response.Headers.Location = new Uri(uri);
            return response;
        }

        #endregion


        public void PutProduct(int id, Product product)
        {
            product.Id = id;
            if (!repository.Update(product))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
        }


        #region DELETE
        ///api/ApiProducts/id
        public HttpResponseMessage DeleteProduct(int id)
        {
            repository.Remove(id);
            
            return new HttpResponseMessage(HttpStatusCode.NoContent);
        }
        #endregion


        [HttpGet]
        //api/{controller}/{action}/{id}
        [ActionName("Thumbnail")]
        public HttpResponseMessage GetThumbnailImage(int id)
        {
            return new HttpResponseMessage(HttpStatusCode.NotImplemented);
        }

        [HttpPost]
        [ActionName("Thumbnail")]
        public void AddThumbnailImage(int id)
        {
            
        }

    }
}
